import dayjs from "dayjs";
import { getWxOpenidByCode, getAppDownloadinfoCheckAppVerson } from "@/api";

import crypto from "./crypto";
import store from "@/store";
import config from "@/common/config";

//工具类
export const TooL = {
  Core: {
    /**
     * 防抖
     * @param {Number} delay
     * @param {Function} func
     */
    debounce(func, delay = 500) {
      let timer = null;
      return function (...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
          func.apply(this, args);
        }, delay);
      };
    },

    /**
     * 节流
     * @date 2024/2/5 - 15:09:14
     *
     * @param {Function} func
     * @param {number} delay
     * @returns {(...args: {}) => void}
     */
    throttle(func, delay = 500) {
      let lastTime = 0;
      return function (...args) {
        const nowTime = Date.now();
        if (nowTime - lastTime > delay) {
          lastTime = nowTime;
          func.apply(this, args);
        }
      };
    },

    /**
     * 异常处理
     * @param {Promise} request
     * @returns {Promise}
     */
    awaitTo(request) {
      return request.then(({ data }) => [null, data]).catch((err) => [err, null]);
    },
    /**
     * 修改标题
     */
    setNavigationBarTitle(title) {
      try {
        uni.setNavigationBarTitle({
          title: title,
        });
      } catch (e) {}
    },
    /**
     * 拨打电话
     * @param {String} phone
     */
    makePhoneCall(phone) {
      if (phone) {
        uni.makePhoneCall({
          phoneNumber: phone, //仅为示例
        });
      } else {
        TooL.Core.showToast("拨打号码不能为空");
      }
    },
    /**
     * opt  object | string
     * to_url object | string
     * 例:
     * this.Tips('/pages/test/test'); 跳转不提示
     * this.Tips({title:'提示'},'/pages/test/test'); 提示并跳转
     * this.Tips({title:'提示'},{tab:1,url:'/pages/index/index'}); 提示并跳转值table上
     * tab=1 一定时间后跳转至 table上
     * tab=2 一定时间后跳转至非 table上
     * tab=3 一定时间后返回上页面
     * tab=4 关闭所有页面跳转至非table上
     * tab=5 关闭当前页面跳转至table上
     */
    Tips: function (opt, to_url) {
      if (typeof opt == "string") {
        to_url = opt;
        opt = {};
      }
      let title = opt.title || "",
        icon = opt.icon || "none",
        endtime = opt.endtime || 1200,
        success = opt.success;
      if (title)
        uni.showToast({
          title: title,
          icon: icon,
          duration: endtime,
          success,
        });
      if (to_url != undefined) {
        if (typeof to_url == "object") {
          let tab = to_url.tab || 1,
            url = to_url.url || "";
          switch (tab) {
            case 1:
              //一定时间后跳转至 table
              setTimeout(function () {
                uni.switchTab({
                  url: url,
                });
              }, endtime);
              break;
            case 2:
              //跳转至非table页面
              setTimeout(function () {
                uni.navigateTo({
                  url: url,
                });
              }, endtime);
              break;
            case 3:
              //返回上页面
              setTimeout(function () {
                uni.navigateBack({
                  delta: parseInt(url),
                });
              }, endtime);
              break;
            case 4:
              //关闭当前所有页面跳转至非table页面
              setTimeout(function () {
                uni.reLaunch({
                  url: url,
                });
              }, endtime);
              break;
            case 5:
              //关闭当前页面跳转至非table页面
              setTimeout(function () {
                uni.redirectTo({
                  url: url,
                });
              }, endtime);
              break;
          }
        } else if (typeof to_url == "function") {
          setTimeout(function () {
            to_url && to_url();
          }, endtime);
        } else {
          //没有提示时跳转不延迟
          setTimeout(
            function () {
              uni.navigateTo({
                url: to_url,
              });
            },
            title ? endtime : 0
          );
        }
      }
    },
    /**
     * 本地保存
     * @param {Object} key
     * @param {Object} value
     */
    setItem(key, value) {
      try {
        uni.setStorageSync(key, value);
      } catch (e) {
        // error
      }
    },
    /**
     * 本地保存读取
     * @param {Object} key
     */
    getItem(key) {
      try {
        const value = uni.getStorageSync(key);
        if (value) {
          return value;
        } else {
          return "";
        }
      } catch (e) {
        // error
      }
    },
    /**
     * 本地删除
     * @param {Object} key
     */
    removeItem(key) {
      try {
        uni.removeStorageSync(key);
      } catch (e) {
        // error
      }
    },
    /**
     * 计算两个经纬度之间的距离
     * lat1 和 lon1 分别是第一个点的纬度和经度，lat2 和 lon2 分别是第二个点的纬度和经度
     * unit 米m，千米km
     */
    getDistance(lat1, lon1, lat2, lon2, unit = "km") {
      const R = 6371; // 地球半径，单位为千米
      const φ1 = (lat1 * Math.PI) / 180; // 第一个点的纬度，转换为弧度
      const φ2 = (lat2 * Math.PI) / 180; // 第二个点的纬度，转换为弧度
      const Δφ = ((lat2 - lat1) * Math.PI) / 180; // 两个点的纬度差值，转换为弧度
      const Δλ = ((lon2 - lon1) * Math.PI) / 180; // 两个点的经度差值，转换为弧度

      const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      let doubleSpeed = 1;
      if (unit == "m") doubleSpeed = 1000;
      return R * c * doubleSpeed; // 两点之间的距离
    },
    /**
     * 获取当前位置的经纬度（异步）
     */
    GetLocationAsync(whetherToPrompt = true) {
      return new Promise((resolve, reject) => {
        TooL.Core.GetLocation((location, isSuccess, err) => {
          if (isSuccess) {
            resolve(location, isSuccess);
          } else {
            reject(new Error({
              location,
              isSuccess,
              err,
            }));
          }
        }, whetherToPrompt);
      });
    },
    /**
     * 获取当前位置的经纬度
     * whetherToPrompt 是否需要报错提示
     */
    GetLocation(callBack, whetherToPrompt = true) {
      // #ifdef APP-PLUS
      let system = uni.getSystemInfoSync(); // 获取系统信息
      if (system.platform === "android") {
        // 判断平台
        var context = plus.android.importClass("android.content.Context");
        var locationManager = plus.android.importClass("android.location.LocationManager");
        var main = plus.android.runtimeMainActivity();
        var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
        if (!mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)) {
          uni.showModal({
            content: "当前未开启定位权限，无法获取定位信息，请前往开启",
            showCancel: true, // 显示取消按钮
            success(res) {
              if (res.confirm) {
                if (!mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)) {
                  var Intent = plus.android.importClass("android.content.Intent");
                  var Settings = plus.android.importClass("android.provider.Settings");
                  var intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                  main.startActivity(intent); // 打开系统设置GPS服务页面
                } else {
                  console.log("GPS功能已开启");
                }
              } else if (res.cancel) {
                console.log("点击了取消");
              }
            },
          });
        }
      }
      // #endif
      uni.getLocation({
        //#ifdef APP-PLUS
        type: "gcj02",
        //#endif
        //#ifndef APP-PLUS
        type: "wgs84",
        //#endif
        altitude: false,
        geocode: true,
        success: (res) => {
          console.log("获取的定位信息：", res);
          let location = {}; // 经度 longitude ， 纬度 latitude
          //#ifdef APP-PLUS
          var addressList = res.address;
          location = {
            longitude: res.longitude,
            latitude: res.latitude,
            address: `${addressList.province}${addressList.city}${addressList.district}${addressList.street}${addressList.streetNum}`,
            addressInfo: res.address,
            // cityCode:res.address.cityCode,
            type: res.type,
          };
          //#endif
          //#ifdef H5 || MP-WEIXIN
          location = {
            longitude: res.longitude,
            latitude: res.latitude,
          };
          //#endif
          if (callBack) callBack(location, true);
        },
        fail: (err) => {
          console.log("获取的定位信息的报错信息：", err);
          // #ifdef MP-BAIDU
          if (err.errCode === 202 || err.errCode === 10003) {
            // 202模拟器 10003真机 user deny
            // this.showConfirm();
          }
          // #endif
          // #ifndef MP-BAIDU
          if (err.errMsg.indexOf("auth deny") >= 0) {
            // #ifdef MP-WEIXIN
            uni.showModal({
              title: "提示",
              content: "需要获取您的地理位置，请前往小程序设置页面开启权限",
              showCancel: false,
              success: function (res) {
                wx.openSetting();
              },
            });
            // #endif
            // #ifdef APP-PLUS
            if (system.platform === "android") {
              // 安卓系统
              // 打开安卓系统设置页面
              uni.navigateTo({
                url:
                  "android.settings.APPLICATION_DETAILS_SETTINGS?packagename=" + getApp().$vm._isH5
                    ? "__UNI__"
                    : getApp().$vm.__wxConfig.appid,
              });
            } else if (system.platform === "ios") {
              // iOS系统
              // 打开iOS系统设置页面
              uni.navigateTo({
                url: "app-settings",
              });
            }
            // #endif
            // #ifdef H5
            TooL.Core.showToast("访问位置被拒绝");
            // #endif
          } else {
            if (whetherToPrompt) {
              TooL.Core.showToast("访问位置被拒绝！请确认定位开启并已授权！");
              console.warn(err.errMsg);
              // TooL.Core.showToast(err.errMsg);
            }
          }
          // #endif
          if (callBack) callBack(err.errMsg, false, err);
        },
      });
    },
    /**
     * 加载框
     * @param {*} text(文字)
     * @param {*} bool(是否显示透明蒙层，防止触摸穿透，默认：false)
     */
    showLoading(text, bool = true) {
      uni.showLoading({
        title: text,
        mask: bool,
      });
    },
    /**
     * 关闭加载框
     */
    hideLoading(delay) {
      if (delay) {
        const timer = setTimeout(() => {
          uni.hideLoading();
          clearTimeout(timer);
        }, delay);
      } else {
        uni.hideLoading();
      }
    },
    /**
     * 弹黑色消息框
     * @param {*} data
     */
    showToast(data, endtime = 2000) {
      if (data.length > 9) {
        // 弹出框提示时长的修改：提示在9个字以内默认时长3秒，超出9个字后，每8个字增加1秒
        let index = data.slice(9).length;
        let indexCeil = Math.ceil(index / 8);
        endtime = endtime + indexCeil * 1000;
      }
      uni.showToast({
        title: data,
        icon: "none",
        duration: endtime,
      });
    },
    /**
     * 读取当前时间
     */
    getGurDateStr() {
      return dayjs().format("YYYY-MM-DD HH:mm:ss");
    },
    /**
     * 时间字符串创建时间对象
     * 在 ios/Safari 中，使用 new Date() 获取的日期格式是：2017/03/15 ，
     * 但是在Android/Chrome中获取的日期格式是：2017-03-15/2017/03/15 。
     */
    newDateStr(date) {
      let d;
      // ios 只接受时间格式为 'yyyy/MM/DD hh:mm:ss' 转换
      if (uni.getSystemInfoSync().platform == "ios" && typeof date === "string") {
        let hd = date.replace(/[TZ]/g, " ").split(/[- : /]/);
        d = new Date(hd[0], hd[1] - 1, hd[2], hd[3] || 0, hd[4] || 0, hd[5] || 0);
      } else {
        d = new Date(date);
      }
      return d;
    },
    /*
     * 合并数组
     */
    SplitArray(list, sp) {
      if (typeof list != "object") return [];
      if (sp === undefined) sp = [];
      for (var i = 0; i < list.length; i++) {
        sp.push(list[i]);
      }
      return sp;
    },
    /**
     * 是否在时间范围里
     * @param {*} inputTime '2023-07-05 21:22:06',
     * @param {*} startTime '05:00:00'/ '05:00'
     * @param {*} endTime '21:22:00' / '21:22'
     * @returns
     */
    isTimeInRange(inputTime, startTime = "05:00", endTime = "21:00") {
      // 获取当前日期
      const currentDate = new Date();
      // 将输入的时间转换为 Date 对象
      // const time = typeof inputTime === "string" ? new Date(inputTime) : inputTime;
      const time = inputTime instanceof Date ? inputTime : TooL.Core.newDateStr(inputTime);

      // 获取输入时间，开始时间和结束时间的小时和分钟
      const [nowHour, nowMinute, nowSeconds] = (() => [time.getHours(), time.getMinutes(), time.getSeconds()])();
      const [startHour, startMinute, startSeconds = 0] = startTime.split(":").map(Number);
      const [endHour, endMinute, endSeconds = 0] = endTime.split(":").map(Number);

      // 创建当天的开始时间和结束时间的 Date 对象
      const refereTime = new Date(currentDate); // 参照时间
      refereTime.setHours(nowHour, nowMinute, nowSeconds); // 将时间的日期调到当天作为参照方便对比
      const startOfDay = new Date(currentDate);
      startOfDay.setHours(startHour, startMinute, startSeconds); // 设置为当天的指定开始时间
      const endOfDay = new Date(currentDate);
      endOfDay.setHours(endHour, endMinute, endSeconds); // 设置为当天的指定结束时间
      // console.log("判断时间是否在范围内", {
      //   refereTime: refereTime.toLocaleString(),
      //   time: time.toLocaleString(), startOfDay: startOfDay.toLocaleString(), endOfDay: endOfDay.toLocaleString()
      // },
      // refereTime >= startOfDay, refereTime <= endOfDay);
      // 判断时间是否在范围内
      return refereTime >= startOfDay && refereTime <= endOfDay;
    },
    /**
     * 计算两个时间内的工时数量
     * @param {*} startTime
     * @param {*} endTime
     * @param {*} startWorkingHour
     * @param {*} endWorkingHour
     * @returns
     */
    calculateWorkingHours(startTime, endTime, startWorkingHour = "00:00", endWorkingHour = "23:59") {
      const start = TooL.Core.newDateStr(startTime);
      const end = TooL.Core.newDateStr(endTime);

      const startHour = startWorkingHour.split(":")[0];
      const endHour = endWorkingHour.split(":")[0];

      const startOfWorkingDay = new Date(start);
      startOfWorkingDay.setHours(parseInt(startHour), 0, 0, 0); // 设置为工作日的起始时间

      const endOfWorkingDay = new Date(end);
      endOfWorkingDay.setHours(parseInt(endHour), 0, 0, 0); // 设置为工作日的结束时间

      let timeDiff = endOfWorkingDay.getTime() - startOfWorkingDay.getTime();

      // 如果结束时间在开始时间之前，表示跨日
      if (end.getTime() < start.getTime()) {
        const endOfPreviousDay = new Date(end);
        endOfPreviousDay.setHours(23, 59, 59, 999); // 设置为前一天的最后一毫秒

        const startOfNextDay = new Date(start);
        startOfNextDay.setHours(0, 0, 0, 0); // 设置为后一天的第一毫秒

        const previousDayDiff = endOfPreviousDay.getTime() - startOfWorkingDay.getTime();
        const nextDayDiff = endOfWorkingDay.getTime() - startOfNextDay.getTime();

        timeDiff = previousDayDiff + nextDayDiff;
      }

      const hourDiff = timeDiff / (1000 * 60 * 60); // 将毫秒转换为小时
      return hourDiff;
    },
    calcDateDayDiff(startTime, endTime) {
      return dayjs(startTime).diff(endTime, "day");
    },
    /** 毫秒转时长格式 6000 -> 00:00:00 */
    convertDurationToTime(duration, mode = "hh:mm:ss") {
      // 将持续时间转换为秒数
      const seconds = Math.floor(duration / 1000);

      // 计算小时、分钟和秒数
      const hours = Math.floor(seconds / 3600);
      const minutes = Math.floor((seconds % 3600) / 60);
      const remainingSeconds = seconds % 60;

      // 格式化为两位数的字符串
      const formattedHours = String(hours).padStart(2, "0");
      const formattedMinutes = String(minutes).padStart(2, "0");
      const formattedSeconds = String(remainingSeconds).padStart(2, "0");

      // 将小时、分钟和秒数连接起来，并用冒号分隔
      let formattedTime = "Error";
      const modeMap = {
        "minute-mode": `${formattedMinutes}'${formattedSeconds}''`,
        "hh:mm:ss": `${formattedHours}:${formattedMinutes}:${formattedSeconds}`,
        "mm:ss": `${formattedMinutes}:${formattedSeconds}`,
        "mm'ss''": `${formattedMinutes}'${formattedSeconds}''`,
        mm: formattedMinutes,
      };
      // console.log(">>>", modeMap, mode, modeMap[mode], duration)
      formattedTime = modeMap[mode];
      return formattedTime;
    },
    /** hh:mm:ss 转毫秒 */
    timeToMilliseconds(time) {
      const [hours, minutes, seconds] = time.split(":").map((n) => parseInt(n));
      const hoursInMilliseconds = hours * 60 * 60 * 1000;
      const minutesInMilliseconds = minutes * 60 * 1000;
      const secondsInMilliseconds = seconds * 1000;
      return hoursInMilliseconds + minutesInMilliseconds + secondsInMilliseconds;
    },
    /** hh:mm:ss 转分钟 */
    timeToMinutes(time) {
      const [hours, minutes, seconds] = time.split(":").map((n) => parseInt(n));
      const hoursToMinutes = hours * 60;
      const totalMinutes = hoursToMinutes + minutes;
      return totalMinutes;
    },
    /* 是否当天 */
    isToday(timeString) {
      if (!timeString) return false;
      const today = dayjs();
      const date = dayjs(timeString);
      return date.isSame(today, "day");
    },
    // 判断时间 a 是否早于时间 b
    isBefore(a, b) {
      return dayjs(a).isBefore(b);
    },
    // 判断时间 a 是否晚于时间 b
    isAfter(a, b) {
      return dayjs(a).isAfter(b);
    },
    // 延迟
    sleep(ms = 1000) {
      return new Promise((resolve) => setTimeout(resolve, ms));
    },
    // 图片等比缩放
    scaleImageDimensions(imageWidth, imageHeight) {
      const res = uni.getSystemInfoSync();

      const screenWidth = res.windowWidth;
      const screenHeight = res.windowHeight;
      const imageAspectRatio = imageWidth / imageHeight;
      console.log("当前设备可用宽高：", res.windowWidth, res.windowHeight, "图片宽高比", imageAspectRatio);
      return {
        width: screenWidth,
        height: screenWidth / imageAspectRatio,
      };
    },
    // 身份证隐藏
    hideSensitiveInfo(idNumber) {
      if (!idNumber) return "";
      const hiddenDigits = "*".repeat(8);
      const maskedIdNumber = idNumber.slice(0, 6) + hiddenDigits + idNumber.slice(-4);
      return maskedIdNumber;
    },
    /*
     * 对象和链接生成最终链接
     */
    ObjectUrl(url, data) {
      let isThereAny = url.indexOf("?");
      Object.keys(data).forEach((v, index) => {
        let datav = data[v];
        if (typeof datav === "object") datav = JSON.stringify(datav);
        if (isThereAny > -1) {
          url += "&" + v + "=" + datav;
        } else {
          if (index == 0) {
            url += "?" + v + "=" + datav;
          } else {
            url += "&" + v + "=" + datav;
          }
        }
      });
      return url;
    },
    /** 版本号对比 */
    compareVersion(v1, v2) {
      v1 = v1.split(".");
      v2 = v2.split(".");
      const len = Math.max(v1.length, v2.length);
      while (v1.length < len) {
        v1.push("0");
      }
      while (v2.length < len) {
        v2.push("0");
      }
      console.log({ v1, v2, len });
      for (let i = 0; i < len; i++) {
        const num1 = parseInt(v1[i]);
        const num2 = parseInt(v2[i]);
        if (num1 > num2) {
          return 1; //大于限定版本
        } else if (num1 < num2) {
          return -1; //小于限定版本
        }
      }
      return 0; //等于限定版本
    },
    /** 判断sdk版本是否大于等于入参版本 */
    isHigherSDKVersion(limitVersion, showErrToast = false) {
      try {
        const res = uni.getSystemInfoSync();
        const SDKVersion = TooL.Core.compareVersion(res.hostSDKVersion, limitVersion);
        if (SDKVersion < 0) {
          if (!showErrToast) return false;
          uni.showModal({
            title: "提示",
            content: "当前微信版本过低，部分功能可能无法使用，建议及时更新",
            confirmText: "我知道了",
            showCancel: false,
          });
          return false;
        } else {
          return true;
        }
      } catch (error) {
        console.error("isHigherSDKVersion ERROR: ", error);
        return false;
      }
    },
    /** 获取当月的所有日期 */
    getAllDatesOfMonth(date) {
      // 获取当前日期
      const currentDate = dayjs(date);

      // 获取本月第一天的日期
      const firstDayOfMonth = currentDate.startOf("month");

      // 获取本月的天数
      const numberOfDays = currentDate.daysInMonth();

      // 生成本月所有日期
      const allDatesOfMonth = [];
      for (let i = 0; i < numberOfDays; i++) {
        const date = firstDayOfMonth.add(i, "day");
        allDatesOfMonth.push(date);
      }

      // // 打印本月所有日期
      // allDatesOfMonth.forEach(date => {
      // 	console.log(date.format('YYYY-MM-DD'));
      // });
      return allDatesOfMonth;
    },
    /** 获取某月的工作日天数 */
    getWeekdayCountInMonth(year, month) {
      if (!year || !month) {
        const date = new Date();
        year = date.getFullYear();
        month = date.getMonth() + 1;
      }
      const daysInMonth = dayjs(`${year}-${month}-01`).daysInMonth(); // 获取该月的总天数
      let weekdayCount = 0;
      for (let day = 1; day <= daysInMonth; day++) {
        const date = dayjs(`${year}-${month}-${day}`);
        if (date.day() !== 0 && date.day() !== 6) {
          weekdayCount++;
        }
      }
      return weekdayCount;
    },
    // 获取两个日期之间的所有日期
    getAllTimesBetween(start, end) {
      const startTime = dayjs(start);
      const endTime = dayjs(end);

      const duration = endTime.diff(startTime, "day");
      const allTimes = [];

      for (let i = 0; i <= duration; i++) {
        const time = startTime.add(i, "day");
        allTimes.push(time.format("YYYY-MM-DD"));
      }

      return allTimes;
    },
    /** 是当天 */
    isToday(date1, date2) {
      const currentTime = dayjs(date1);
      const targetTime = dayjs(date2);
      return currentTime.isSame(targetTime, "day");
    },
    isAfterTime(currtime, atime) {
      const currentTime = dayjs(currtime);
      const targetTime = dayjs(atime);
      return currentTime >= targetTime;
    },
    /** dayjs 格式化时间 */
    dayjsFormat(date, format = "YYYY-MM-DD") {
      const fdate = dayjs(date);
      return fdate.format(format);
    },
    // 时分秒拼接当天日期   返回字符串 '12:00'---->YYYY-MM-DD 12:00:00
    timejsFormat(time, date) {
      let currentDate = this.dayjsFormat(new Date(), "YYYY-MM-DD");
      if (date) {
        currentDate = this.dayjsFormat(date, "YYYY-MM-DD");
      }
      const fdate = this.dayjsFormat(currentDate + " " + time, "YYYY-MM-DD HH:mm:ss");
      return fdate;
    },
    /**
     * web-View链接携带通用参数
     */
    webViewLinkAddress(url) {
      let list = {
        access_token: store.getters.token,
        roleId: store.getters.roleId,
        userId: store.getters.userInfo.id,
        // redirectToUrl: encodeURIComponent('/ApplicationMnagement/index') //需要跳转的页面
      };
      // #ifdef APP-PLUS || MP-WEIXIN
      const mobileInfo = uni.getSystemInfoSync();
      if (mobileInfo.safeAreaInsets) {
        list.safeAreaInsets = JSON.stringify(mobileInfo.safeAreaInsets);
      }
      // #endif
      if (url.indexOf("http") <= -1) {
        // url = Sys.webViewUrl + url;
      }
      // 平台类型
      // #ifdef H5
      list.platformType = "H5";
      // #endif
      // #ifdef APP-PLUS
      list.platformType = "APP";
      // #endif
      // #ifdef MP-WEIXIN
      list.platformType = "MP-WEIXIN";
      // #endif
      return encodeURIComponent(TooL.Core.ObjectUrl(url, list));
    },
    formatTimeDiff(targetTime) {
      const now = dayjs();
      const target = dayjs(targetTime);

      const diffInMilliseconds = now.diff(target, "millisecond");
      const diffInSeconds = Math.round(diffInMilliseconds / 1000);
      const diffInMinutes = Math.round(diffInSeconds / 60);
      const diffInHours = Math.round(diffInMinutes / 60);
      const diffInDays = Math.round(diffInHours / 24);

      if (diffInMilliseconds < 0) {
        // 目标时间在未来，可以选择特定的处理方式
        return targetTime;
      } else if (diffInSeconds < 60) {
        return diffInSeconds + "秒前";
      } else if (diffInMinutes < 60) {
        return diffInMinutes + "分钟前";
      } else if (diffInHours < 24) {
        return diffInHours + "小时前";
      } else if (diffInDays < 7) {
        return diffInDays + "天前";
      } else {
        // 目标时间超过一周，可以选择特定的处理方式
        return targetTime;
      }
    },
    /**
     * 检查版本更新
     * @param {*} callBack
     * @param {*} autoShowPop 自动开起更新弹窗
     * @param {*} showIsNew 没最新版时是否弹窗提醒已是最新版
     */
    checkUpgrade: function (callBack, autoShowPop = false, showIsNew = false) {
      let callList = {
        code: 0,
        msg: "", //报错信息
        OldVersion: "", //本地版本号
        appVersionNum: "", //远程版本号
        appUpdateUrl: "", //下载地址
        updateContent: "", //更新内容
      };
      // appType 应用类型（用于多端多app）
      let list = {
        appType: config.APP_TYPE_ID,
        appEdition: 1, // android/ios
      };
      let new_platform = plus.os.name;
      console.log("***手机操作系统***" + new_platform);
      if (new_platform == "Android") list.appEdition = 1;
      else if (new_platform == "iOS") list.appEdition = 2;
      plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
        callList.OldVersion = widgetInfo.version;
        console.log("***plus - getProperty***", widgetInfo, list);
        getAppDownloadinfoCheckAppVerson(list)
          .then((res) => {
            console.log("***CheckAppVerson***", res);
            if (
              res.code == 200 &&
              res.data &&
              TooL.Core.checkUpgradeCompareVersion(callList.OldVersion, res.data.appVersionNum)
            ) {
              callList.code = res.code;
              callList.msg = res.msg;
              callList = Object.assign(callList, res.data);
              callBack(callList);
              console.log("appupdate-res", res);
              if (autoShowPop) {
                /** 下载文件链接的处理 (现在获取到的地址是重定向地址，直接下载会有问题) */
                if (/\?appdownUrl\=/.test(res.data.appUpdateUrl)) {
                  // https://saas.zhtuoyu.cn/enclosure/enclosure/App/%E6%99%BA%E6%85%A7%E6%89%98%E8%82%B2.html?appdownUrl=https://saas.zhtuoyu.cn/enclosure/enclosure/App/%E6%99%BA%E6%85%A7%E6%89%98%E8%82%B2.apk
                  let appdownUrl = res.data.appUpdateUrl.split("?appdownUrl=")[1];
                  res.data.appUpdateUrl = appdownUrl;
                }
                /**  */
                const updateInfo = {
                  // 版本更新内容 支持<br>自动换行
                  describe: res.data.updateContent,
                  edition_url: res.data.appUpdateUrl, //apk、wgt包下载地址或者应用市场地址  安卓应用市场 market://details?id=xxxx 苹果store itms-apps://itunes.apple.com/cn/app/xxxxxx
                  edition_force: res.data.force || 0, //是否强制更新 0代表否 1代表是
                  package_type: res.data.updateType, //0是整包升级（apk或者appstore或者安卓应用市场） 1是wgt升级
                  edition_issue: res.data.issue || 1, //是否发行  0否 1是 为了控制上架应用市场审核时不能弹出热更新框
                  edition_number: res.data.appVersionNum, //版本号 最重要的manifest里的版本号 （检查更新主要以服务器返回的edition_number版本号是否大于当前app的版本号来实现是否更新）
                  edition_name: res.data.appVersionNum, // 版本名称 manifest里的版本名称
                  edition_silence: res.data.silence || 0, // 是否静默更新 0代表否 1代表是
                };
                // uni.navigateTo({
                // 	url: `/subHome/public/updateApp/updateApp?obj=${JSON.stringify(updateInfo)}`
                // })
                uni.navigateTo({
                  url: `/uni_modules/rt-uni-update/components/rt-uni-update/rt-uni-update?obj=${JSON.stringify(
                    updateInfo
                  )}`,
                });
              }
            } else {
              if (showIsNew && res.data) {
                uni.showModal({
                  title: "提示",
                  content: "已是最新版本" + callList.OldVersion,
                  showCancel: false,
                });
              }
              return callBack(callList);
            }
          })
          .catch((err) => {
            console.error("***CheckAppVerson***", err);
            callList.msg = err;
            callBack(callList);
          });
      });
    },
    //判断版本差异
    checkUpgradeCompareVersion(ov, nv) {
      console.log("compareVersion:当前版本=" + ov + " 更新版本=" + nv);
      if (!ov || !nv || ov == "" || nv == "") return false;
      var b = false,
        ova = ov.split(".", 4),
        nva = nv.split(".", 4);
      for (var i = 0; i < ova.length && i < nva.length; i++) {
        var so = ova[i],
          no = parseInt(so),
          sn = nva[i],
          nn = parseInt(sn);
        if (nn > no || sn.length > so.length) return true;
        else if (nn < no) return false;
      }
      if (nva.length > ova.length && 0 == nv.indexOf(ov)) return true;
    },
    /**
     * 服务器中的素材
     */
    SetImgLink: function (src, useMateria = true) {
      if (src) {
        if (src.indexOf("http") > -1 || src.indexOf("https") > -1) {
          return src;
        } else {
          // 开发时使用本地 地址
          // console.log("VUE_APP_USE_LOCAL_STATIC ", process.env.VUE_APP_USE_LOCAL_STATIC)
          if (process.env.VUE_APP_USE_LOCAL_STATIC == 1 && useMateria) return src;
          if (useMateria) return config.materialURL + src;
          else return config.baseUrl + src;
        }
      } else {
        return null;
      }
    },
    /**
     * 金额换算
     */
    Money: function (val) {
      if (typeof val == "string") {
        if (val) {
          if (validatechinese(val)) {
            return 0;
          } else {
            return Math.round(parseFloat(val) * 100) / 100;
          }
        } else {
          return 0;
        }
      } else {
        if (val) return Math.round(parseFloat(val) * 100) / 100;
        else return 0;
      }
    },
    // 获取微信code,换区openid
    getOpenId: function () {
      return new Promise((res, rej) => {
        uni.login({
          provider: "weixin",
          success: (loginRes) => {
            let jsonForm = {
              ["Pay-Code"]: "SOJOURN_PAY_XCX",
              ["Tenant-Id"]: config.getTenantId(),
              ["Pay-Env"]: "WX_XCX",
              code: loginRes.code,
            };
            getWxOpenidByCode(jsonForm)
              .then(({ data, code }) => {
                if (code == 200) res(JSON.parse(data).openid);
                else {
                  return res("");
                }
                // _self.WXappid = JSON.parse(data.data).openid
              })
              .catch((err) => {
                console.log(err);
                res("");
              });
          },
        });
      });
    },
    isStringEmptyOrWhitespace: function (str) {
      if (str === null || str === undefined) {
        return true; // 字符串为 null 或 undefined，被视为空字符
      }

      // 使用 trim() 方法去除字符串两端的空格，并判断结果是否为空字符串
      return str.trim() === "";
    },
    /**
     * 分割","连接的资源链接，并按格式返回
     * @param {String} links  资源链接
     * @param {Boolean} returnType 是否返回文件类型 false 时直接返回分割的字符串数组
     */
    splitFileLinks(links, returnType = true) {
      const linkArray = links.split(",");
      if (!returnType) {
        if (linkArray.length === 0) return "";
        // if (linkArray.length === 1) return links;
        return linkArray;
      } else {
        return linkArray.map((v) => {
          return {
            url: v,
            type: TooL.Core.getFileType(v),
          };
        });
      }
    },
    // 判断文件类型
    getFileType(url) {
      var extension = url.split(".").pop().toLowerCase();
      if (extension.match(/(jpg|jpeg|png|gif)$/)) {
        return "image";
      } else if (extension.match(/(mp4|avi|wmv|mov)$/)) {
        return "video";
      } else if (extension.match(/(mp3|wav|ogg)$/)) {
        return "audio";
      } else {
        return "other";
      }
    },
    /**
     * 接口加密数据解密
     *  判断header中是否含有data-encrypted字段，如果含有则解密， 无则返回原有数据
     * @param {*} requestData
     * @returns
     */
    requestDataEncrypt(requestData) {
      if (!requestData || !requestData.header) return requestData;
      if (
        (requestData.header["data-encrypted"] && requestData.header["data-encrypted"] == 1) ||
        (requestData.header["Data-Encrypted"] && requestData.header["Data-Encrypted"] == 1)
      ) {
        try {
          const decrypt = crypto.decryptAES(requestData.data);
          const newRequestData = {
            data: JSON.parse(decrypt),
            errMsg: requestData.errMsg,
            statusCode: requestData.statusCode,
            header: requestData.header,
          };
          // console.log('解密前：', requestData.data, '\n解密后：', newRequestData.data)
          return newRequestData;
        } catch (error) {
          console.error("==> decrypt Error", error);
          return requestData;
        }
      } else {
        return requestData;
      }
    },
    gegetQueryStringValue(name) {
      var items = null;
      try {
        var search = document.location.search;
        var pattern = new RegExp("[?&]" + name + "=([^&]+)", "g");
        var matcher = pattern.exec(search);
        if (null != matcher) {
          try {
            items = decodeURIComponent(decodeURIComponent(matcher[1]));
          } catch (e) {
            try {
              items = decodeURIComponent(matcher[1]);
            } catch (e) {
              items = matcher[1];
            }
          }
        }
      } catch (dd) {}
      return items;
    },
  },
};

